#include <stdio.h> 
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "common_func.h"

extern const unsigned int fft_input[512];
extern volatile unsigned int fft_output[512];
volatile unsigned char flag_dma;
unsigned int * fft_hardware_input;
unsigned int * fft_hardware_output;

int main(int argc, char** argv)
{
	int i;

	//传给DMA的地址使用物理地址
	fft_hardware_input = (unsigned int *)0x1f401000;
	fft_hardware_output = (unsigned int *)0x1f402000;
	flag_dma = 0;

	printf("FFT test begin\n");

	//开启第一次DMA传输，搬运内存中的输入数据至FFT模块
	RegWrite(0xbf300004,fft_input);//dma saddr
	RegWrite(0xbf300008,fft_hardware_input);//dma daddr
	RegWrite(0xbf30000c,512);//dma length
    
	//使能DMA中断和FFT中断
	RegWrite(0xbf20f004,0x00);//edge
	RegWrite(0xbf20f008,0xc00);//pol
	RegWrite(0xbf20f00c,0xfff);//clr
	RegWrite(0xbf20f000,0xc00);//en

	//开启DMA传输
	RegWrite(0xbf300000,0x1);//dma en

	//等待FFT计算完成，并完成输出数据搬运
	while(flag_dma!=2);

	init_dcache_line(fft_output);
	printf("FFT test end\n");

	printf("output real:\n");
	for(i=0;i<512;i++){
		printf("%04x\n",fft_output[i] >> 16);
	}

	printf("output imag:\n");
	for(i=0;i<512;i++){
		printf("%04x\n",fft_output[i] & 0xffff);
	}

	return 0;
}


void HWI0_IntrHandler(void)
{	
	unsigned int int_state;
	int_state = RegRead(0xbf20f014);

	if((int_state & 0x10) == 0x10){
		Timer_IntrHandler();
	}
	else if(int_state & 0x400){
		DMA_IntrHandler();
	}
	else if(int_state & 0x800){
		FFT_IntrHandler();
	}
	else if(int_state & 0xf){
		Button_IntrHandler(int_state & 0xf);
	}
}

void DMA_IntrHandler(void)
{	
	//清DMA中断
	RegWrite(0xbf300000,0x2);
	if(flag_dma == 0){
		//开始512点FFT/IFFT
#ifdef IFFT_TEST
		RegWrite(0xbf400000,0x0f);
#else
		RegWrite(0xbf400000,0x0d);
#endif
		//标志完成第一次DMA搬运
		flag_dma = 1;
	}else if(flag_dma == 1){
		//标志完成第二次DMA搬运
		flag_dma = 2;
	}
}

void FFT_IntrHandler(void)
{
	//清FFT中断
	RegWrite(0xbf400000,0x0);
	//开启第二次DMA传输，搬运FFT模块中的输出数据至内存
	RegWrite(0xbf300004,fft_hardware_output);//dma saddr
	RegWrite(0xbf300008,fft_output);//dma daddr
	RegWrite(0xbf30000c,512);//dma length
	RegWrite(0xbf300000,0x1);//dma en
}

void Timer_IntrHandler(void)
{
	RegWrite(0xbf20f108,0);
	RegWrite(0xbf20f108,1);
}

void Button_IntrHandler(unsigned char button_state)
{
	if((button_state & 0b1000) == 0b1000){
		RegWrite(0xbf20f00c,0x8);//clr
	}
	else if((button_state & 0b0100) == 0b0100){
		RegWrite(0xbf20f00c,0x4);//clr
	}
	else if((button_state & 0b0010) == 0b0010){
		RegWrite(0xbf20f00c,0x2);//clr
	}
	else if((button_state & 0b0001) == 0b0001){
		RegWrite(0xbf20f00c,0x1);//clr
	}
}
